<script setup lang="ts">
import { ECheckbox, EInput, EVirtualList } from 'exploria-ui';
import { computed, reactive, ref } from 'vue';

const eventMap = {
    GET: Array.from({ length: 20 }, (_, index) => {
        return {
            label: '获取' + index,
            code: 'api_get' + index,
        };
    }),
    POST: Array.from({ length: 34 }, (_, index) => {
        return {
            label: '提交' + index,
            code: 'api_post' + index,
        };
    }),
    DELETE: Array.from({ length: 14 }, (_, index) => {
        return {
            label: '删除' + index,
            code: 'api_delete' + index,
        };
    }),
} as {
    [category: string]: {
        label: string;
        code: string;
    }[];
};

const searchText = ref('');

const colCount = ref(3);

interface Row {
    rowKey: string;
    type: 'category' | 'eventNameList';
    items: { label: string; value?: string }[];
}

const computedData = computed<Row[]>(() => {
    const list: Row[] = [];

    for (const category in eventMap) {
        const matchedList = eventMap[category]!.filter((item) =>
            item.label.includes(searchText.value),
        );

        if (matchedList.length) {
            // 添加标题
            list.push({
                rowKey: category,
                type: 'category',
                items: [{ label: category }],
            });
            // 根据 colCount 来构建每一行数据
            for (
                let rowIndex = 0;
                rowIndex < Math.ceil(matchedList.length / colCount.value);
                rowIndex++
            ) {
                // 一行数据，其中包含 colCount 个元素
                const eventListInRow = matchedList.slice(
                    rowIndex * colCount.value,
                    (rowIndex + 1) * colCount.value,
                );

                // 构建 rowKey
                const rowKey = eventListInRow.reduce((a, b) => a + b.code, '');
                list.push({
                    rowKey,
                    type: 'eventNameList',
                    items: eventListInRow.map((item) => {
                        return { label: item.label, value: item.code };
                    }),
                });
            }
        }
    }
    return list;
});

const handleSizeChange = (width: number) => {
    if (width <= 370) {
        colCount.value = 1;
    } else if (width < 800) {
        colCount.value = 2;
    } else {
        colCount.value = 3;
    }
};

const selectedMap = reactive<{
    [value: string]: boolean;
}>({});

const selectedAll = computed({
    get() {
        const selectedCount = Object.entries(selectedMap).filter(
            (item) => item[1],
        ).length;
        const allCount = Object.values(eventMap).flat().length;
        return selectedCount === allCount && allCount !== 0;
    },
    set(checked) {
        // 全选的是所有原始数据，而不是搜索过滤过的数据
        const eventList = Object.values(eventMap).flat();

        eventList.forEach((item) => {
            selectedMap[item.code] = checked;
        });
    },
});
</script>

<template>
    <div class="comprehensive-case">
        <div class="top">
            <ECheckbox v-model="selectedAll"> 全选</ECheckbox>
            <EInput
                type="text"
                v-model="searchText"
                placeholder="请输入"
                clearable
            >
                <template #prefix>
                    <i class="iconfont icon-seacrh" style="font-size: 15px" />
                </template>
            </EInput>
        </div>
        <EVirtualList
            v-size-ob="(width: number) => handleSizeChange(width)"
            :data="computedData"
            :container-height="270"
            :item-height="30"
        >
            <template #row="{ row }: { row: Row }">
                <div
                    v-if="row.type === 'category'"
                    class="category"
                    :key="row.rowKey"
                >
                    {{ row.items[0]!.label }}
                </div>
                <div v-else class="row">
                    <div
                        class="col"
                        v-for="item of row.items"
                        :key="row.rowKey + item.value"
                    >
                        <ECheckbox
                            :model-value="selectedMap[item.value!] ?? false"
                            @update:model-value="
                                (checked) =>
                                    (selectedMap[item.value!] = checked)
                            "
                        >
                            {{ item.label }}
                        </ECheckbox>
                    </div>
                    <!-- 占位 -->
                    <div
                        class="col"
                        v-for="i in colCount - row.items.length"
                        :key="i"
                    />
                </div>
            </template>
            <template #empty></template>
        </EVirtualList>
    </div>
</template>

<style scoped lang="scss">
@import './iconfont/iconfont.css';

.comprehensive-case {
    .top {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 10px;

        .one-input {
            width: 230px;
            height: 30px;
        }
    }

    .e-virtual-list {
        .category {
            font-size: 13px;
            color: #606060;
        }

        .row {
            display: flex;
            align-items: center;
            justify-content: space-between;

            .col {
                flex: 1 0 0;
            }
        }
    }
}
</style>
